/*
 * Clase con metodos de acceso a las Tablas de Simbolos para el lenguaje C Minus.
 * 
 * Basado en el proyecto descrito en: 
 * Louden, K. (1997). Compiler Construction: Principles and Practice. Boston: PWS.
 * 
 * @ Project: Compiler
 * @ File Name: Tables.java
 */
package cml.analyzing;

import java.util.ArrayList;
import java.util.ListIterator;

public class Tables {
	
	/*
	 * Busca un simbolo de variable por nombre.
	 * 
	 * @param	name			nombre del simbolo
	 * @param	lookInGlobal	indica si debe buscar en el bloque global, la primera tabla
	 * @param	tables			la lista de tablas donde buscar
	 */
	public static Symbol lookupVarSymbol(String name, boolean lookInGlobal, ArrayList<SymTable> tables) {
		
		ListIterator<SymTable> lit = tables.listIterator(tables.size() - 1);
		
		SymTable table = tables.get(tables.size() - 1);
		
		do {
			
			if(table.isActive()) {
				
				Symbol sym = table.getSymbol(name);
				
				if(sym != null)
					return sym;
			}
			
			if(lit.hasPrevious())
				table = lit.previous();
			else lookInGlobal = false;
		}
		while(lit.hasPrevious() || lookInGlobal);
		
		return null;
	}
	
	/*
	 * Busca un simbolo de funcion por nombre.
	 * 
	 * @param	name		nombre de la funcion
	 * @param	tables		la lista de tablas donde buscar
	 */
	public static FuncSymbol lookupFuncSymbol(String name, ArrayList<SymTable> tables) {
		
		SymTable table = tables.get(Analyzer.GLOBAL_TABLE);
		FuncSymbol sym = (FuncSymbol)table.getSymbol(name);
		
		return (sym != null) ? sym : null;
	}
	
	/*
	 * Busca una Tabla de Simbolos por nombre.
	 * 
	 * @param	name		nombre de la tabla
	 * @param	tables		la lista de tablas donde buscar
	 * @return	la tabla
	 */
	public static SymTable lookupSymTable(String name, ArrayList<SymTable> tables) {
		
		ListIterator<SymTable> lit = tables.listIterator();
		
		SymTable table;
		
		while(lit.hasNext()) {
			
			table = lit.next();
			
			if(table.getName().equals(name))
				return table;
		}
		
		return null;
	}
}
